home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / LITTLE / P3SRC.ZIP / ATARI / SPHERES.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-25  |  16.3 KB  |  896 lines

  1. /****************************************************************************
  2. *                spheres.c
  3. *
  4. *  This module implements the sphere primitive.
  5. *
  6. *  from Persistence of Vision(tm) Ray Tracer
  7. *  Copyright 1996 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other 
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If 
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "povray.h"
  26. #include "vector.h"
  27. #include "povproto.h"
  28. #include "bbox.h"
  29. #include "matrices.h"
  30. #include "objects.h"
  31. #include "spheres.h"
  32.  
  33.  
  34.  
  35. /*****************************************************************************
  36. * Local preprocessor defines
  37. ******************************************************************************/
  38.  
  39. #define DEPTH_TOLERANCE 1.0e-6
  40.  
  41.  
  42.  
  43. /*****************************************************************************
  44. * Static functions
  45. ******************************************************************************/
  46. static int All_Sphere_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  47. static int All_Ellipsoid_Intersections PARAMS((OBJECT *Object, RAY *Ray, ISTACK *Depth_Stack));
  48. static int Inside_Sphere PARAMS((VECTOR IPoint, OBJECT *Object));
  49. static int Inside_Ellipsoid PARAMS((VECTOR IPoint, OBJECT *Object));
  50. static void Sphere_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  51. static void Ellipsoid_Normal PARAMS((VECTOR Result, OBJECT *Object, INTERSECTION *Inter));
  52. static void Translate_Sphere PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  53. static void Rotate_Sphere PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  54. static void Scale_Sphere PARAMS((OBJECT *Object, VECTOR Vector, TRANSFORM *Trans));
  55. static void Invert_Sphere PARAMS((OBJECT *Object));
  56.  
  57.  
  58.  
  59. /*****************************************************************************
  60. * Local variables
  61. ******************************************************************************/
  62.  
  63. static METHODS Sphere_Methods =
  64. {
  65.   All_Sphere_Intersections,
  66.   Inside_Sphere, Sphere_Normal,
  67.   Copy_Sphere,
  68.   Translate_Sphere, Rotate_Sphere,
  69.   Scale_Sphere, Transform_Sphere, Invert_Sphere,
  70.   Destroy_Sphere
  71. };
  72.  
  73.  
  74.  
  75. static METHODS Ellipsoid_Methods =
  76. {
  77.   All_Ellipsoid_Intersections,
  78.   Inside_Ellipsoid, Ellipsoid_Normal,
  79.   Copy_Sphere,
  80.   Translate_Sphere, Rotate_Sphere,
  81.   Scale_Sphere, Transform_Sphere, Invert_Sphere,
  82.   Destroy_Sphere
  83. };
  84.  
  85.  
  86.  
  87. /*****************************************************************************
  88. *
  89. * FUNCTION
  90. *
  91. *   All_Sphere_Intersection
  92. *
  93. * INPUT
  94. *   
  95. * OUTPUT
  96. *   
  97. * RETURNS
  98. *   
  99. * AUTHOR
  100. *
  101. *   ?
  102. *   
  103. * DESCRIPTION
  104. *
  105. *   -
  106. *
  107. * CHANGES
  108. *
  109. *   -
  110. *
  111. ******************************************************************************/
  112.  
  113. static int All_Sphere_Intersections(Object, Ray, Depth_Stack)
  114. OBJECT *Object;
  115. RAY *Ray;
  116. ISTACK *Depth_Stack;
  117. {
  118.   register int Intersection_Found;
  119.   DBL Depth1, Depth2;
  120.   VECTOR IPoint;
  121.   SPHERE *Sphere = (SPHERE *)Object;
  122.  
  123.   Intersection_Found = FALSE;
  124.  
  125.   if (Intersect_Sphere(Ray, Sphere->Center, Sqr(Sphere->Radius), &Depth1, &Depth2))
  126.   {
  127.     if ((Depth1 > DEPTH_TOLERANCE) && (Depth1 < Max_Distance))
  128.     {
  129.       VEvaluateRay(IPoint, Ray->Initial, Depth1, Ray->Direction);
  130.  
  131.       if (Point_In_Clip(IPoint, Object->Clip))
  132.       {
  133.         push_entry(Depth1, IPoint, Object, Depth_Stack);
  134.  
  135.         Intersection_Found = TRUE;
  136.       }
  137.     }
  138.  
  139.     if ((Depth2 > DEPTH_TOLERANCE) && (Depth2 < Max_Distance))
  140.     {
  141.       VEvaluateRay(IPoint, Ray->Initial, Depth2, Ray->Direction);
  142.  
  143.       if (Point_In_Clip(IPoint, Object->Clip))
  144.       {
  145.         push_entry(Depth2, IPoint, Object, Depth_Stack);
  146.  
  147.         Intersection_Found = TRUE;
  148.       }
  149.     }
  150.   }
  151.  
  152.   return(Intersection_Found);
  153. }
  154.  
  155.  
  156.  
  157. /*****************************************************************************
  158. *
  159. * FUNCTION
  160. *
  161. *   All_Ellipsoid_Intersection
  162. *
  163. * INPUT
  164. *   
  165. * OUTPUT
  166. *   
  167. * RETURNS
  168. *   
  169. * AUTHOR
  170. *
  171. *   ?
  172. *   
  173. * DESCRIPTION
  174. *
  175. *   -
  176. *
  177. * CHANGES
  178. *
  179. *   -
  180. *
  181. ******************************************************************************/
  182.  
  183. static int All_Ellipsoid_Intersections(Object, Ray, Depth_Stack)
  184. OBJECT *Object;
  185. RAY *Ray;
  186. ISTACK *Depth_Stack;
  187. {
  188.   register int Intersection_Found;
  189.   DBL Depth1, Depth2, len;
  190.   VECTOR IPoint;
  191.   RAY New_Ray;
  192.   SPHERE *Sphere = (SPHERE *)Object;
  193.  
  194.   /* Transform the ray into the ellipsoid's space */
  195.  
  196.   MInvTransPoint(New_Ray.Initial, Ray->Initial, ((SPHERE *)Object)->Trans);
  197.   MInvTransDirection(New_Ray.Direction, Ray->Direction, ((SPHERE *)Object)->Trans);
  198.  
  199.   VLength(len, New_Ray.Direction);
  200.   VInverseScaleEq(New_Ray.Direction, len);
  201.  
  202.   Intersection_Found = FALSE;
  203.  
  204.   if (Intersect_Sphere(&New_Ray, Sphere->Center, Sqr(Sphere->Radius), &Depth1, &Depth2))
  205.   {
  206.     if ((Depth1 > DEPTH_TOLERANCE) && (Depth1 < Max_Distance))
  207.     {
  208.       VEvaluateRay(IPoint, New_Ray.Initial, Depth1, New_Ray.Direction);
  209.  
  210.       MTransPoint(IPoint, IPoint, ((SPHERE *)Object)->Trans);
  211.  
  212.       if (Point_In_Clip(IPoint, Object->Clip))
  213.       {
  214.         push_entry(Depth1 / len, IPoint, Object, Depth_Stack);
  215.  
  216.         Intersection_Found = TRUE;
  217.       }
  218.     }
  219.  
  220.     if ((Depth2 > DEPTH_TOLERANCE) && (Depth2 < Max_Distance))
  221.     {
  222.       VEvaluateRay(IPoint, New_Ray.Initial, Depth2, New_Ray.Direction);
  223.  
  224.       MTransPoint(IPoint, IPoint, ((SPHERE *)Object)->Trans);
  225.  
  226.       if (Point_In_Clip(IPoint, Object->Clip))
  227.       {
  228.         push_entry(Depth2 / len, IPoint, Object, Depth_Stack);
  229.  
  230.         Intersection_Found = TRUE;
  231.       }
  232.     }
  233.   }
  234.  
  235.   return(Intersection_Found);
  236. }
  237.  
  238.  
  239.  
  240. /*****************************************************************************
  241. *
  242. * FUNCTION
  243. *
  244. *   Intersect_Sphere
  245. *
  246. * INPUT
  247. *
  248. *   Ray     - Ray to test intersection with
  249. *   Center  - Center of the sphere
  250. *   Radius2 - Squared radius of the sphere
  251. *   Depth1  - Lower intersection distance
  252. *   Depth2  - Upper intersection distance
  253. *   
  254. * OUTPUT
  255. *   
  256. * RETURNS
  257. *   
  258. * AUTHOR
  259. *
  260. *   ?
  261. *   
  262. * DESCRIPTION
  263. *
  264. *   -
  265. *
  266. * CHANGES
  267. *
  268. *   -
  269. *
  270. ******************************************************************************/
  271.  
  272. int Intersect_Sphere(Ray, Center, Radius2, Depth1, Depth2)
  273. RAY *Ray;
  274. VECTOR Center;
  275. DBL Radius2;
  276. DBL *Depth1, *Depth2;
  277. {
  278.   DBL OCSquared, t_Closest_Approach, Half_Chord, t_Half_Chord_Squared;
  279.   VECTOR Origin_To_Center;
  280.  
  281.   Increase_Counter(stats[Ray_Sphere_Tests]);
  282.  
  283.   VSub(Origin_To_Center, Center, Ray->Initial);
  284.  
  285.   VDot(OCSquared, Origin_To_Center, Origin_To_Center);
  286.  
  287.   VDot(t_Closest_Approach, Origin_To_Center, Ray->Direction);
  288.  
  289.   if ((OCSquared >= Radius2) && (t_Closest_Approach < EPSILON))
  290.   {
  291.     return(FALSE);
  292.   }
  293.  
  294.   t_Half_Chord_Squared = Radius2 - OCSquared + Sqr(t_Closest_Approach);
  295.  
  296.   if (t_Half_Chord_Squared > EPSILON)
  297.   {
  298.     Half_Chord = sqrt(t_Half_Chord_Squared);
  299.  
  300.     *Depth1 = t_Closest_Approach - Half_Chord;
  301.     *Depth2 = t_Closest_Approach + Half_Chord;
  302.  
  303.     Increase_Counter(stats[Ray_Sphere_Tests_Succeeded]);
  304.  
  305.     return(TRUE);
  306.   }
  307.  
  308.   return(FALSE);
  309. }
  310.  
  311.  
  312.  
  313. /*****************************************************************************
  314. *
  315. * FUNCTION
  316. *
  317. *   Inside_Sphere
  318. *
  319. * INPUT
  320. *   
  321. * OUTPUT
  322. *   
  323. * RETURNS
  324. *   
  325. * AUTHOR
  326. *
  327. *   ?
  328. *   
  329. * DESCRIPTION
  330. *
  331. *   -
  332. *
  333. * CHANGES
  334. *
  335. *   -
  336. *
  337. ******************************************************************************/
  338.  
  339. static int Inside_Sphere(IPoint, Object)
  340. VECTOR IPoint;
  341. OBJECT *Object;
  342. {
  343.   DBL OCSquared;
  344.   VECTOR Origin_To_Center;
  345.  
  346.   VSub(Origin_To_Center, ((SPHERE *)Object)->Center, IPoint);
  347.  
  348.   VDot(OCSquared, Origin_To_Center, Origin_To_Center);
  349.  
  350.   if (Test_Flag(Object, INVERTED_FLAG))
  351.   {
  352.     return(OCSquared > Sqr(((SPHERE *)Object)->Radius));
  353.   }
  354.   else
  355.   {
  356.     return(OCSquared < Sqr(((SPHERE *)Object)->Radius));
  357.   }
  358. }
  359.  
  360.  
  361.  
  362. /*****************************************************************************
  363. *
  364. * FUNCTION
  365. *
  366. *   Inside_Ellipsoid
  367. *
  368. * INPUT
  369. *
  370. * OUTPUT
  371. *   
  372. * RETURNS
  373. *   
  374. * AUTHOR
  375. *
  376. *   ?
  377. *   
  378. * DESCRIPTION
  379. *
  380. *   -
  381. *
  382. * CHANGES
  383. *
  384. *   -
  385. *
  386. ******************************************************************************/
  387.  
  388. static int Inside_Ellipsoid(IPoint, Object)
  389. VECTOR IPoint;
  390. OBJECT *Object;
  391. {
  392.   DBL OCSquared;
  393.   VECTOR Origin_To_Center, New_Point;
  394.  
  395.   /* Transform the point into the sphere's space */
  396.  
  397.   MInvTransPoint(New_Point, IPoint, ((SPHERE *)Object)->Trans);
  398.  
  399.   VSub(Origin_To_Center, ((SPHERE *)Object)->Center, New_Point);
  400.  
  401.   VDot(OCSquared, Origin_To_Center, Origin_To_Center);
  402.  
  403.   if (Test_Flag(Object, INVERTED_FLAG))
  404.   {
  405.     return(OCSquared > Sqr(((SPHERE *)Object)->Radius));
  406.   }
  407.   else
  408.   {
  409.     return(OCSquared < Sqr(((SPHERE *)Object)->Radius));
  410.   }
  411. }
  412.  
  413.  
  414.  
  415. /*****************************************************************************
  416. *
  417. * FUNCTION
  418. *
  419. *   Sphere_Normal
  420. *
  421. * INPUT
  422. *   
  423. * OUTPUT
  424. *   
  425. * RETURNS
  426. *   
  427. * AUTHOR
  428. *
  429. *   ?
  430. *   
  431. * DESCRIPTION
  432. *
  433. *   -
  434. *
  435. * CHANGES
  436. *
  437. *   -
  438. *
  439. ******************************************************************************/
  440.  
  441. static void Sphere_Normal(Result, Object, Inter)
  442. OBJECT *Object;
  443. VECTOR Result;
  444. INTERSECTION *Inter;
  445. {
  446.   VSub(Result, Inter->IPoint, ((SPHERE *)Object)->Center);
  447.  
  448.   VInverseScaleEq(Result, ((SPHERE *)Object)->Radius);
  449. }
  450.  
  451.  
  452.  
  453. /*****************************************************************************
  454. *
  455. * FUNCTION
  456. *
  457. *   Ellipsoid_Normal
  458. *
  459. * INPUT
  460. *   
  461. * OUTPUT
  462. *   
  463. * RETURNS
  464. *   
  465. * AUTHOR
  466. *
  467. *   ?
  468. *   
  469. * DESCRIPTION
  470. *
  471. *   -
  472. *
  473. * CHANGES
  474. *
  475. *   -
  476. *
  477. ******************************************************************************/
  478.  
  479. static void Ellipsoid_Normal(Result, Object, Inter)
  480. OBJECT *Object;
  481. VECTOR Result;
  482. INTERSECTION *Inter;
  483. {
  484.   VECTOR New_Point;
  485.  
  486.   /* Transform the point into the sphere's space */
  487.  
  488.   MInvTransPoint(New_Point, Inter->IPoint, ((SPHERE *)Object)->Trans);
  489.  
  490.   VSub(Result, New_Point, ((SPHERE *)Object)->Center);
  491.  
  492.   MTransNormal(Result, Result, ((SPHERE *)Object)->Trans);
  493.  
  494.   VNormalize(Result, Result);
  495. }
  496.  
  497.  
  498.  
  499. /*****************************************************************************
  500. *
  501. * FUNCTION
  502. *
  503. *   Copy_Shere
  504. *
  505. * INPUT
  506. *   
  507. * OUTPUT
  508. *   
  509. * RETURNS
  510. *   
  511. * AUTHOR
  512. *
  513. *   ?
  514. *   
  515. * DESCRIPTION
  516. *
  517. *   -
  518. *
  519. * CHANGES
  520. *
  521. *   -
  522. *
  523. ******************************************************************************/
  524.  
  525. void *Copy_Sphere(Object)
  526. OBJECT *Object;
  527. {
  528.   SPHERE *New;
  529.  
  530.   New = Create_Sphere();
  531.  
  532.   *New = *((SPHERE *)Object);
  533.  
  534.   New->Trans = Copy_Transform(((SPHERE *)Object)->Trans);
  535.  
  536.   return(New);
  537. }
  538.  
  539.  
  540.  
  541. /*****************************************************************************
  542. *
  543. * FUNCTION
  544. *
  545. *   Translate_Sphere
  546. *
  547. * INPUT
  548. *
  549. * OUTPUT
  550. *
  551. * RETURNS
  552. *
  553. * AUTHOR
  554. *
  555. *   ?
  556. *
  557. * DESCRIPTION
  558. *
  559. *   -
  560. *
  561. * CHANGES
  562. *
  563. *   -
  564. *
  565. ******************************************************************************/
  566.  
  567. static void Translate_Sphere(Object, Vector, Trans)
  568. OBJECT *Object;
  569. VECTOR Vector;
  570. TRANSFORM *Trans;
  571. {
  572.   SPHERE *Sphere = (SPHERE *) Object;
  573.  
  574.   if (Sphere->Trans == NULL)
  575.   {
  576.     VAddEq(Sphere->Center, Vector);
  577.  
  578.     Compute_Sphere_BBox(Sphere);
  579.   }
  580.   else
  581.   {
  582.     Transform_Sphere(Object, Trans);
  583.   }
  584. }
  585.  
  586.  
  587.  
  588. /*****************************************************************************
  589. *
  590. * FUNCTION
  591. *
  592. *   Rotate_Sphere
  593. *
  594. * INPUT
  595. *
  596. * OUTPUT
  597. *   
  598. * RETURNS
  599. *   
  600. * AUTHOR
  601. *
  602. *   ?
  603. *   
  604. * DESCRIPTION
  605. *
  606. *   -
  607. *
  608. * CHANGES
  609. *
  610. *   -
  611. *
  612. ******************************************************************************/
  613.  
  614. static void Rotate_Sphere(Object, Vector, Trans)
  615. OBJECT *Object;
  616. VECTOR Vector;
  617. TRANSFORM *Trans;
  618. {
  619.   SPHERE *Sphere = (SPHERE *) Object;
  620.  
  621.   if (Sphere->Trans == NULL)
  622.   {
  623.     MTransPoint(Sphere->Center, Sphere->Center, Trans);
  624.  
  625.     Compute_Sphere_BBox(Sphere);
  626.   }
  627.   else
  628.   {
  629.     Transform_Sphere(Object, Trans);
  630.   }
  631. }
  632.  
  633.  
  634.  
  635. /*****************************************************************************
  636. *
  637. * FUNCTION
  638. *
  639. *   Scale_Sphere
  640. *
  641. * INPUT
  642. *   
  643. * OUTPUT
  644. *   
  645. * RETURNS
  646. *   
  647. * AUTHOR
  648. *
  649. *   ?
  650. *   
  651. * DESCRIPTION
  652. *
  653. *   -
  654. *
  655. * CHANGES
  656. *
  657. *   -
  658. *
  659. ******************************************************************************/
  660.  
  661. static void Scale_Sphere(Object, Vector, Trans)
  662. OBJECT *Object;
  663. VECTOR Vector;
  664. TRANSFORM *Trans;
  665. {
  666.   SPHERE *Sphere = (SPHERE *) Object;
  667.  
  668.   if ((Vector[X] != Vector[Y]) || (Vector[X] != Vector[Z]))
  669.   {
  670.     if (Sphere->Trans == NULL)
  671.     {
  672.       Sphere->Methods = &Ellipsoid_Methods;
  673.  
  674.       Sphere->Trans = Create_Transform();
  675.     }
  676.   }
  677.  
  678.   if (Sphere->Trans == NULL)
  679.   {
  680.     VScaleEq(Sphere->Center, Vector[X]);
  681.  
  682.     Sphere->Radius *= Vector[X];
  683.  
  684.     Compute_Sphere_BBox(Sphere);
  685.   }
  686.   else
  687.   {
  688.     Transform_Sphere(Object, Trans);
  689.   }
  690. }
  691.  
  692.  
  693.  
  694. /*****************************************************************************
  695. *
  696. * FUNCTION
  697. *
  698. *   Invert_Sphere
  699. *
  700. * INPUT
  701. *   
  702. * OUTPUT
  703. *   
  704. * RETURNS
  705. *   
  706. * AUTHOR
  707. *
  708. *   ?
  709. *   
  710. * DESCRIPTION
  711. *
  712. *   -
  713. *
  714. * CHANGES
  715. *
  716. *   -
  717. *
  718. ******************************************************************************/
  719.  
  720. static void Invert_Sphere(Object)
  721. OBJECT *Object;
  722. {
  723.   Invert_Flag(Object, INVERTED_FLAG);
  724. }
  725.  
  726.  
  727.  
  728. /*****************************************************************************
  729. *
  730. * FUNCTION
  731. *
  732. *   Create_Sphere
  733. *
  734. * INPUT
  735. *   
  736. * OUTPUT
  737. *   
  738. * RETURNS
  739. *   
  740. * AUTHOR
  741. *
  742. *   ?
  743. *   
  744. * DESCRIPTION
  745. *
  746. *   -
  747. *
  748. * CHANGES
  749. *
  750. *   -
  751. *
  752. ******************************************************************************/
  753.  
  754. SPHERE *Create_Sphere()
  755. {
  756.   SPHERE *New;
  757.  
  758.   New = (SPHERE *)POV_MALLOC(sizeof(SPHERE), "sphere");
  759.  
  760.   INIT_OBJECT_FIELDS(New, SPHERE_OBJECT, &Sphere_Methods)
  761.  
  762.   Make_Vector(New->Center, 0.0, 0.0, 0.0);
  763.  
  764.   New->Radius = 1.0;
  765.  
  766.   New->Trans = NULL;
  767.  
  768.   return(New);
  769. }
  770.  
  771.  
  772.  
  773. /*****************************************************************************
  774. *
  775. * FUNCTION
  776. *
  777. *   Transform_Sphere
  778. *
  779. * INPUT
  780. *   
  781. * OUTPUT
  782. *   
  783. * RETURNS
  784. *   
  785. * AUTHOR
  786. *
  787. *   ?
  788. *   
  789. * DESCRIPTION
  790. *
  791. *   -
  792. *
  793. * CHANGES
  794. *
  795. *   -
  796. *
  797. ******************************************************************************/
  798.  
  799. void Transform_Sphere(Object, Trans)
  800. OBJECT *Object;
  801. TRANSFORM *Trans;
  802. {
  803.   SPHERE *Sphere = (SPHERE *)Object;
  804.  
  805.   if (Sphere->Trans == NULL)
  806.   {
  807.     Sphere->Methods = &Ellipsoid_Methods;
  808.  
  809.     Sphere->Trans = Create_Transform();
  810.   }
  811.  
  812.   Compose_Transforms(Sphere->Trans, Trans);
  813.  
  814.   Compute_Sphere_BBox(Sphere);
  815. }
  816.  
  817.  
  818.  
  819. /*****************************************************************************
  820. *
  821. * FUNCTION
  822. *
  823. *   Destroy_Sphere
  824. *
  825. * INPUT
  826. *   
  827. * OUTPUT
  828. *   
  829. * RETURNS
  830. *   
  831. * AUTHOR
  832. *
  833. *   ?
  834. *   
  835. * DESCRIPTION
  836. *
  837. *   -
  838. *
  839. * CHANGES
  840. *
  841. *   -
  842. *
  843. ******************************************************************************/
  844.  
  845. void Destroy_Sphere(Object)
  846. OBJECT *Object;
  847. {
  848.   Destroy_Transform(((SPHERE *)Object)->Trans);
  849.  
  850.   POV_FREE (Object);
  851. }
  852.  
  853.  
  854.  
  855. /*****************************************************************************
  856. *
  857. * FUNCTION
  858. *
  859. *   Compute_Sphere_BBox
  860. *
  861. * INPUT
  862. *
  863. *   Sphere - Sphere
  864. *   
  865. * OUTPUT
  866. *
  867. *   Sphere
  868. *   
  869. * RETURNS
  870. *   
  871. * AUTHOR
  872. *
  873. *   Dieter Bayer
  874. *   
  875. * DESCRIPTION
  876. *
  877. *   Calculate the bounding box of a sphere.
  878. *
  879. * CHANGES
  880. *
  881. *   Aug 1994 : Creation.
  882. *
  883. ******************************************************************************/
  884.  
  885. void Compute_Sphere_BBox(Sphere)
  886. SPHERE *Sphere;
  887. {
  888.   Make_BBox(Sphere->BBox, Sphere->Center[X] - Sphere->Radius, Sphere->Center[Y] - Sphere->Radius,  Sphere->Center[Z] - Sphere->Radius,
  889.     2.0 * Sphere->Radius, 2.0 * Sphere->Radius, 2.0 * Sphere->Radius);
  890.  
  891.   if (Sphere->Trans != NULL)
  892.   {
  893.     Recompute_BBox(&Sphere->BBox, Sphere->Trans);
  894.   }
  895. }
  896.